package io.plus.engine.pulse;

import io.plus.engine.pulse.task.CloseCode;
import lombok.extern.slf4j.Slf4j;
import tool.plus.$;

import java.nio.ByteBuffer;


@Slf4j
public class IoUtils {


    public static boolean check(AsynchronousSocketChannelContext asynchronousSocketChannelContext) {
        if (asynchronousSocketChannelContext.isWaitingClose) {
            return false;
        }
        Boolean open = null;
        if (asynchronousSocketChannelContext.asynchronousSocketChannel == null) {//
            log.error("{}, 请检查此异常, asynchronousSocketChannel is null, isClosed:{}, isRemoved:{}, {} ",//
                    asynchronousSocketChannelContext,//
                    asynchronousSocketChannelContext.isClosed,//
                    asynchronousSocketChannelContext.isRemoved,//
                    $.getStackTrace());//
            return false;
        } else {
            open = asynchronousSocketChannelContext.asynchronousSocketChannel.isOpen();
            if (open) {
                if (asynchronousSocketChannelContext.isClosed || asynchronousSocketChannelContext.isRemoved) {
                    log.info("{}, isopen:{}, isClosed:{}, isRemoved:{}", asynchronousSocketChannelContext, open, asynchronousSocketChannelContext.isClosed, asynchronousSocketChannelContext.isRemoved);
                    try {
                        Io.close(asynchronousSocketChannelContext,
                                "asynchronousSocketChannel is open, but clientChannelContext isClosed: " + asynchronousSocketChannelContext.isClosed + ", isRemoved: " + asynchronousSocketChannelContext.isRemoved, CloseCode.CHANNEL_NOT_OPEN);
                    } catch (Throwable e) {
                        log.error(e.toString(), e);
                    }
                    return false;
                } else {
                    return true;
                }

            } else {
                log.info("{}, 可能对方关闭了连接, isopen:{}, isClosed:{}, isRemoved:{}", asynchronousSocketChannelContext, open, asynchronousSocketChannelContext.isClosed, asynchronousSocketChannelContext.isRemoved);
                Io.close(asynchronousSocketChannelContext, "asynchronousSocketChannel is not open, 可能对方关闭了连接", CloseCode.CHANNEL_NOT_OPEN);
                return false;
            }

        }


    }

    /**
     * 组合两个bytebuffer，把可读部分的组合成一个新的bytebuffer
     */
    public static ByteBuffer composite(ByteBuffer byteBuffer1, ByteBuffer byteBuffer2) {
        int capacity = byteBuffer1.remaining() + byteBuffer2.remaining();
        ByteBuffer byteBuffer = ByteBuffer.allocate(capacity);

        byteBuffer.put(byteBuffer1);
        byteBuffer.put(byteBuffer2);

        byteBuffer.position(0);
        byteBuffer.limit(byteBuffer.capacity());
        return byteBuffer;
    }

    /**
     * @param src 本方法不会改变position等指针变量
     */
    public static ByteBuffer copy(ByteBuffer src) {

        return copy(src, src.position(), src.limit());
    }

    public static ByteBuffer copy(ByteBuffer src, int startindex, int endindex) {
        int size = endindex - startindex;
        int initPosition = src.position();
        int initLimit = src.limit();

        src.position(startindex);
        src.limit(endindex);
        ByteBuffer ret = ByteBuffer.allocate(size);
        ret.put(src);
        ret.flip();

        src.position(initPosition);
        src.limit(initLimit);
        return ret;
    }
}
